﻿using System;
using System.Collections.Generic;
using System.Text;
using ZedGraph;

namespace Statistics
{
    /// <summary>
    /// Предоставляет функции и структуры для хранения списка списков пар точек
    /// </summary>
    [Serializable]
    public class PointsForReport
    {
        /// <summary>
        /// Список отдельных точек, не предназначенных для графиков (например: Tср...)
        /// </summary>
        public List<double> SinglePoints {get; set;}
        /// <summary>
        /// Наименования отдельных точек (например: "Тср"...)
        /// </summary>
        public List<string> SinglePointNames {get; set;}
        /// <summary>
        /// Список пар точек: категория, название, список точек
        /// </summary>
        private SortedList<string,SortedList<string,PointPairList>> categoryPointList2;

        /// <summary>
        /// Список категорий
        /// </summary>
        public int CategoryCount
        {
            get { return categoryPointList2.Count; }
        }
        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="NLists">Кoличество списков пар точек</param>
        public PointsForReport()
        {
            categoryPointList2 = new SortedList<string, SortedList<string, PointPairList>>();
            SinglePointNames = new List<string>();
            SinglePoints = new List<double>();
        }

        /// <summary>
        /// Добавить точку в список
        /// </summary>
        /// <param name="listName">Имя списка</param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void Add(string listName, string CatName, double x, double y)
        {
            categoryPointList2[CatName][listName].Add(x, y);
        }
        /// <summary>
        /// Удалить все списки
        /// </summary>
        public void ClearAll()
        {
            categoryPointList2.Clear();
        }
        /// <summary>
        /// Удалить все точки из конкретного списка
        /// </summary>
        public void ClearAll(string CatName, string listName)
        {
            categoryPointList2[CatName][listName].Clear();
        }
        /// <summary>
        /// Удалить все списки и создать новый список списков
        /// </summary>
        /// <param name="NLists">Количество списков</param>
        public void RedefineListNumber(int NLists)
        {
            categoryPointList2.Clear();
            categoryPointList2.Capacity = NLists;
        }
        /// <summary>
        /// Получить значение единичной точки по ее названию
        /// </summary>
        /// <param name="Name">название точки</param>
        /// <returns>значение точки</returns>
        public double GetSinglePoint(string Name)
        {
            int id = SinglePointNames.FindIndex(delegate (string s)
            {
                return (s == Name);
            });
            return SinglePoints[id];
        }
        /// <summary>
        /// Получить список точек по имени и категории
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        public PointPairList GetList(string Name, string Category)
        {
            return categoryPointList2[Category][Name];
        }
        /// <summary>
        /// Создать поименованную точку
        /// </summary>
        /// <param name="Name">Имя точки</param>
        /// <param name="value">Значение точки</param>
        public void CreateSinglePoint(string name, double value)
        {
            SinglePointNames.Add(name);
            SinglePoints.Add(value);
        }
        /// <summary>
        /// Создать поименованный список
        /// </summary>
        /// <param name="Name">Имя списка</param>
        /// <param name="catName">Имя категории</param>
        public void CreateNewList(string name, string catName)
        {
            if (categoryPointList2.Keys.Contains(catName))//если такая категория уже существует
            {
                if (!categoryPointList2[catName].Keys.Contains(name))
                {//если списка с таким ключем нет
                    categoryPointList2[catName].Add(name, new PointPairList());
                }
                else
                {//иначе просто очистим его
                    categoryPointList2[catName][name].Clear();
                }
            }
            else
            {
                categoryPointList2.Add(catName, new SortedList<string, PointPairList>());
                categoryPointList2[catName].Add(name, new PointPairList());
            }
        }
        /// <summary>
        /// Получить список отчетности только по 1 категории
        /// </summary>
        /// <param name="categoryName">имя категории</param>
        /// <returns></returns>
        public List<PointPairList> GetListsOfOneCategory(string categoryName)
        {
            List<PointPairList> pf = new List<PointPairList>();
            foreach (string listName in categoryPointList2[categoryName].Keys)
            {
                //скопируем этот список
                pf.Add(categoryPointList2[categoryName][listName].Clone());
            }
            return pf;
        }

        /// <summary>
        /// Получить список отчетности только по 1 категории
        /// </summary>
        /// <returns></returns>
        public List<PointPairList> GetListsOfOneCategory(int categoryID)
        {
            List<PointPairList> pf = new List<PointPairList>();
            string cat = categoryPointList2.Keys[categoryID];
            foreach (string listName in categoryPointList2[cat].Keys)
            {
                //скопируем этот список
                pf.Add(categoryPointList2[cat][listName].Clone());
            }
            return pf;
        }
        /// <summary>
        /// Создать новый список и заполнить его значениями другого списка точек
        /// </summary>
        /// <param name="listName">Имя списка</param>
        /// <param name="categoryName">Категория списка</param>
        /// <param name="copiedList">Копируемый список</param>
        public void CopyList(string listName, string categoryName, PointPairList copiedList)
        {
            CreateNewList(listName, categoryName);
            categoryPointList2[categoryName][listName] = copiedList.Clone();
        }

        public string GetListName(int categoryID, int listID)
        {
            string cat = categoryPointList2.Keys[categoryID];
            string name = categoryPointList2[cat].Keys[listID];
            return name;
        }

        public PointsForReport GetPointListOfOneCategory(string categoryName)
        {
            //если нет такой категории
            if (!categoryPointList2.Keys.Contains(categoryName))
                return null;

            PointsForReport pf = new PointsForReport();
            foreach (string listName in categoryPointList2[categoryName].Keys)
            {
                //скопируем этот список
                pf.CopyList(listName, categoryName, categoryPointList2[categoryName][listName].Clone());
            }
            return pf;
        }
        public void ClearSinglePointList()
        {
            SinglePointNames.Clear();
            SinglePoints.Clear();
        }
       
    }
}
